package com.automotive.can1939.can;

import com.automotive.can1939.model.J1939Frame;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * J1939测试数据生成器
 * 生成符合SAE J1939标准的测试数据
 */
public class J1939TestDataGenerator {

    private static final Random random = new Random();

    /**
     * 获取所有J1939测试帧
     */
    public static List<J1939Frame> getAllJ1939TestFrames() {
        List<J1939Frame> frames = new ArrayList<>();

        frames.addAll(getEngineTestFrames());
        frames.addAll(getVehicleTestFrames());
        frames.addAll(getTransmissionTestFrames());
        frames.addAll(getBrakeTestFrames());
        frames.addAll(getEnvironmentTestFrames());

        return frames;
    }

    /**
     * 获取发动机相关测试帧
     */
    public static List<J1939Frame> getEngineTestFrames() {
        List<J1939Frame> frames = new ArrayList<>();

        // EEC1 - 电子发动机控制器1 (发动机转速)
        J1939Frame eec1 = createEEC1Frame(1800 + random.nextInt(2000)); // 1800-3800 RPM
        frames.add(eec1);

        // EEC2 - 电子发动机控制器2 (油门位置)
        J1939Frame eec2 = createEEC2Frame(random.nextInt(101)); // 0-100%
        frames.add(eec2);

        // ET1 - 发动机温度1 (冷却液温度)
        J1939Frame et1 = createET1Frame(70 + random.nextInt(50)); // 70-120°C
        frames.add(et1);

        return frames;
    }

    /**
     * 获取车辆动态测试帧
     */
    public static List<J1939Frame> getVehicleTestFrames() {
        List<J1939Frame> frames = new ArrayList<>();

        // CCVS - 巡航控制/车辆速度
        J1939Frame ccvs = createCCVSFrame(random.nextInt(121)); // 0-120 km/h
        frames.add(ccvs);

        // VD - 车辆距离
        J1939Frame vd = createVDFrame(100000 + random.nextInt(900000)); // 100-1000 km
        frames.add(vd);

        // HOURS - 发动机小时数
        J1939Frame hours = createHOURSFrame(1000 + random.nextInt(9000)); // 1000-10000 hours
        frames.add(hours);

        return frames;
    }

    /**
     * 获取传动系统测试帧
     */
    public static List<J1939Frame> getTransmissionTestFrames() {
        List<J1939Frame> frames = new ArrayList<>();

        // ETC1 - 电子传动控制器1
        J1939Frame etc1 = createETC1Frame(random.nextInt(4000)); // 0-4000 RPM
        frames.add(etc1);

        return frames;
    }

    /**
     * 获取制动系统测试帧
     */
    public static List<J1939Frame> getBrakeTestFrames() {
        List<J1939Frame> frames = new ArrayList<>();

        // EBC1 - 电子制动控制器1
        J1939Frame ebc1 = createEBC1Frame(random.nextInt(4)); // ABS状态 0-3
        frames.add(ebc1);

        return frames;
    }

    /**
     * 获取环境条件测试帧
     */
    public static List<J1939Frame> getEnvironmentTestFrames() {
        List<J1939Frame> frames = new ArrayList<>();

        // AMB - 环境条件
        J1939Frame amb = createAMBFrame(-10 + random.nextInt(51)); // -10 to 40°C
        frames.add(amb);

        return frames;
    }

    /**
     * 创建EEC1帧 - 发动机转速
     */
    public static J1939Frame createEEC1Frame(int rpm) {
        J1939Frame frame = new J1939Frame();
        frame.setPriority(3);
        frame.setPgn(J1939Constants.PGN_EEC1);
        frame.setSourceAddress(0x00);

        // 构建数据 - SPN 190: 发动机转速
        byte[] data = new byte[8];
        data[0] = (byte) 0xFF; // 扭矩模式 - 不可用
        data[1] = (byte) 0xFF; // 驾驶员需求扭矩 - 不可用
        data[2] = (byte) 0xFF; // 实际发动机扭矩 - 不可用

        // 发动机转速 (分辨率: 0.125 rpm/bit)
        int rpmValue = (int) (rpm / 0.125);
        data[3] = (byte) (rpmValue & 0xFF);
        data[4] = (byte) ((rpmValue >> 8) & 0xFF);

        data[5] = (byte) 0xFF; // 源地址 - 不可用
        data[6] = (byte) 0xFF; // 启动器模式 - 不可用
        data[7] = (byte) 0xFF; // 需求扭矩限制 - 不可用

        frame.setData(data);
        frame.setPgnName("电子发动机控制器1");
        frame.setSpnName(String.format("发动机转速: %d RPM", rpm));

        return frame;
    }

    /**
     * 创建EEC2帧 - 油门位置
     */
    public static J1939Frame createEEC2Frame(int throttlePercent) {
        J1939Frame frame = new J1939Frame();
        frame.setPriority(3);
        frame.setPgn(J1939Constants.PGN_EEC2);
        frame.setSourceAddress(0x00);

        byte[] data = new byte[8];
        data[0] = (byte) 0xFF; // 加速踏板位置1 - 不可用

        // SPN 558: 油门踏板1位置 (分辨率: 0.4%/bit)
        data[1] = (byte) (throttlePercent / 0.4);

        data[2] = (byte) 0xFF; // 发动机负荷 - 不可用
        data[3] = (byte) 0xFF; // 遥控加速踏板位置 - 不可用
        data[4] = (byte) 0xFF; // 加速踏板位置2 - 不可用
        data[5] = (byte) 0xFF; // 车辆加速度限制状态 - 不可用
        data[6] = (byte) 0xFF; // 加速使能开关 - 不可用
        data[7] = (byte) 0xFF; // 路面坡度 - 不可用

        frame.setData(data);
        frame.setPgnName("电子发动机控制器2");
        frame.setSpnName(String.format("油门位置: %d%%", throttlePercent));

        return frame;
    }

    /**
     * 创建ET1帧 - 发动机温度
     */
    public static J1939Frame createET1Frame(int temperature) {
        J1939Frame frame = new J1939Frame();
        frame.setPriority(6);
        frame.setPgn(J1939Constants.PGN_ENGINE_TEMPERATURE_1);
        frame.setSourceAddress(0x00);

        byte[] data = new byte[8];

        // SPN 110: 发动机冷却液温度 (偏移: -40°C)
        data[0] = (byte) (temperature + 40);

        data[1] = (byte) 0xFF; // 燃油温度1 - 不可用
        data[2] = (byte) (temperature + 35); // 发动机机油温度1
        data[3] = (byte) 0xFF; // 涡轮机油温度 - 不可用
        data[4] = (byte) 0xFF; // 发动机进气温度 - 不可用
        data[5] = (byte) 0xFF; // 发动机原始机油温度 - 不可用
        data[6] = (byte) 0xFF; // 保留
        data[7] = (byte) 0xFF; // 保留

        frame.setData(data);
        frame.setPgnName("发动机温度1");
        frame.setSpnName(String.format("冷却液温度: %d°C", temperature));

        return frame;
    }

    /**
     * 创建CCVS帧 - 车辆速度
     */
    public static J1939Frame createCCVSFrame(int speedKmh) {
        J1939Frame frame = new J1939Frame();
        frame.setPriority(6);
        frame.setPgn(J1939Constants.PGN_CRUISE_CONTROL_VEHICLE_SPEED);
        frame.setSourceAddress(0x17);

        byte[] data = new byte[8];
        data[0] = (byte) 0xFF; // 两速轴开关 - 不可用

        // SPN 84: 车轮速度 (分辨率: 1/256 km/h/bit)
        int speedValue = (int) (speedKmh * 256);
        data[1] = (byte) (speedValue & 0xFF);
        data[2] = (byte) ((speedValue >> 8) & 0xFF);

        data[3] = (byte) 0xFF; // 巡航控制状态 - 不可用
        data[4] = (byte) 0xFF; // 离合器开关 - 不可用
        data[5] = (byte) 0xFF; // 制动开关 - 不可用
        data[6] = (byte) 0xFF; // 加速使能开关 - 不可用
        data[7] = (byte) 0xFF; // 恢复开关 - 不可用

        frame.setData(data);
        frame.setPgnName("巡航控制/车辆速度");
        frame.setSpnName(String.format("车辆速度: %d km/h", speedKmh));

        return frame;
    }

    /**
     * 创建VD帧 - 车辆距离
     */
    public static J1939Frame createVDFrame(long distanceMeters) {
        J1939Frame frame = new J1939Frame();
        frame.setPriority(6);
        frame.setPgn(J1939Constants.PGN_VEHICLE_DISTANCE);
        frame.setSourceAddress(0x17);

        byte[] data = new byte[8];

        // SPN 244: 总车辆距离 (分辨率: 5 m/bit)
        long distanceValue = distanceMeters / 5;
        data[0] = (byte) (distanceValue & 0xFF);
        data[1] = (byte) ((distanceValue >> 8) & 0xFF);
        data[2] = (byte) ((distanceValue >> 16) & 0xFF);
        data[3] = (byte) ((distanceValue >> 24) & 0xFF);

        // SPN 245: 行程距离
        data[4] = (byte) 0xFF;
        data[5] = (byte) 0xFF;
        data[6] = (byte) 0xFF;
        data[7] = (byte) 0xFF;

        frame.setData(data);
        frame.setPgnName("车辆距离");
        frame.setSpnName(String.format("总距离: %.1f km", distanceMeters / 1000.0));

        return frame;
    }

    /**
     * 创建HOURS帧 - 发动机小时数
     */
    public static J1939Frame createHOURSFrame(double hours) {
        J1939Frame frame = new J1939Frame();
        frame.setPriority(6);
        frame.setPgn(J1939Constants.PGN_ENGINE_HOURS);
        frame.setSourceAddress(0x00);

        byte[] data = new byte[8];

        // SPN 247: 总发动机小时数 (分辨率: 0.05 h/bit)
        long hoursValue = (long) (hours / 0.05);
        data[0] = (byte) (hoursValue & 0xFF);
        data[1] = (byte) ((hoursValue >> 8) & 0xFF);
        data[2] = (byte) ((hoursValue >> 16) & 0xFF);
        data[3] = (byte) ((hoursValue >> 24) & 0xFF);

        data[4] = (byte) 0xFF; // 保留
        data[5] = (byte) 0xFF; // 保留
        data[6] = (byte) 0xFF; // 保留
        data[7] = (byte) 0xFF; // 保留

        frame.setData(data);
        frame.setPgnName("发动机小时数");
        frame.setSpnName(String.format("运行时间: %.1f h", hours));

        return frame;
    }

    /**
     * 创建ETC1帧 - 传动输出轴转速
     */
    public static J1939Frame createETC1Frame(int outputRpm) {
        J1939Frame frame = new J1939Frame();
        frame.setPriority(6);
        frame.setPgn(J1939Constants.PGN_ETC1);
        frame.setSourceAddress(0x03);

        byte[] data = new byte[8];
        data[0] = (byte) 0xFF; // 传动扭矩转换器锁定离合器 - 不可用
        data[1] = (byte) 0xFF; // 传动换档器位置 - 不可用

        // SPN 523: 传动输出轴转速 (分辨率: 0.125 rpm/bit)
        int rpmValue = (int) (outputRpm / 0.125);
        data[2] = (byte) (rpmValue & 0xFF);
        data[3] = (byte) ((rpmValue >> 8) & 0xFF);

        data[4] = (byte) 0xFF; // 传动输入轴转速 - 不可用
        data[5] = (byte) 0xFF; // 传动输入轴转速 - 不可用
        data[6] = (byte) 0xFF; // 传动请求范围 - 不可用
        data[7] = (byte) 0xFF; // 传动当前范围 - 不可用

        frame.setData(data);
        frame.setPgnName("电子传动控制器1");
        frame.setSpnName(String.format("输出轴转速: %d RPM", outputRpm));

        return frame;
    }

    /**
     * 创建EBC1帧 - ABS状态
     */
    public static J1939Frame createEBC1Frame(int absStatus) {
        J1939Frame frame = new J1939Frame();
        frame.setPriority(6);
        frame.setPgn(J1939Constants.PGN_EBC1);
        frame.setSourceAddress(0x0B);

        byte[] data = new byte[8];

        // SPN 521: ABS状态 (位6-7)
        data[0] = (byte) ((absStatus & 0x03) << 6);

        data[1] = (byte) 0xFF; // ASR状态 - 不可用
        data[2] = (byte) 0xFF; // ATC状态 - 不可用
        data[3] = (byte) 0xFF; // 制动踏板位置 - 不可用
        data[4] = (byte) 0xFF; // ABS卸载阀状态 - 不可用
        data[5] = (byte) 0xFF; // ABS卸载阀状态 - 不可用
        data[6] = (byte) 0xFF; // 制动应用压力 - 不可用
        data[7] = (byte) 0xFF; // 制动主缸压力 - 不可用

        frame.setData(data);
        frame.setPgnName("电子制动控制器1");

        String statusText;
        switch (absStatus) {
            case 0: statusText = "关闭"; break;
            case 1: statusText = "开启"; break;
            case 2: statusText = "错误"; break;
            default: statusText = "不可用"; break;
        }
        frame.setSpnName(String.format("ABS状态: %s", statusText));

        return frame;
    }

    /**
     * 创建AMB帧 - 环境温度
     */
    public static J1939Frame createAMBFrame(int ambientTemp) {
        J1939Frame frame = new J1939Frame();
        frame.setPriority(6);
        frame.setPgn(J1939Constants.PGN_AMBIENT_CONDITIONS);
        frame.setSourceAddress(0x19);

        byte[] data = new byte[8];
        data[0] = (byte) 0xFF; // 大气压力 - 不可用
        data[1] = (byte) 0xFF; // 大气压力 - 不可用
        data[2] = (byte) 0xFF; // 发动机进气温度 - 不可用

        // SPN 171: 环境空气温度 (偏移: -40°C)
        data[3] = (byte) (ambientTemp + 40);

        data[4] = (byte) 0xFF; // 空调高压 - 不可用
        data[5] = (byte) 0xFF; // 空调高压 - 不可用
        data[6] = (byte) 0xFF; // 空调低压 - 不可用
        data[7] = (byte) 0xFF; // 保留

        frame.setData(data);
        frame.setPgnName("环境条件");
        frame.setSpnName(String.format("环境温度: %d°C", ambientTemp));

        return frame;
    }

    /**
     * 创建自定义J1939帧
     */
    public static J1939Frame createCustomJ1939Frame(int priority, int pgn, int sourceAddress, String dataHex) {
        J1939Frame frame = new J1939Frame();
        frame.setPriority(priority);
        frame.setPgn(pgn);
        frame.setSourceAddress(sourceAddress);

        // 解析十六进制数据
        String[] hexBytes = dataHex.trim().split("\\s+");
        byte[] data = new byte[Math.min(hexBytes.length, 8)];

        for (int i = 0; i < data.length; i++) {
            try {
                data[i] = (byte) Integer.parseInt(hexBytes[i], 16);
            } catch (NumberFormatException e) {
                data[i] = 0;
            }
        }

        frame.setData(data);
        frame.setPgnName(J1939DataParser.getPgnName(pgn));
        frame.setSpnName("自定义数据: " + dataHex);

        return frame;
    }
}
